#include "StdAfx.h"
#include "Map2ClientTransform.h"
#include "ogr_core.h"
#include "ogr_srs_api.h"

CMap2ClientTransform::CMap2ClientTransform(void)
{
	m_sourProjection = NULL;
	m_destProjection = NULL;
}

CMap2ClientTransform::~CMap2ClientTransform(void)
{
	if (m_destProjection)
	{
		pj_free(m_destProjection);
	}
	if (m_sourProjection)
	{
		pj_free(m_sourProjection);
	}
}

void CMap2ClientTransform::setParameters(CSize* clientSize,CMapLayerEnvelope* mapExtend)
{
	m_clientSize = *clientSize;
	m_curEnvelope = *mapExtend;

	double xPixelsPerMapUnit = (double)clientSize->cx/(mapExtend->width());
    double yPixelsPerMapUnit = (double)clientSize->cy/(mapExtend->height());
	CPointGeometry centerPoint = mapExtend->centerPoint();	
	if (xPixelsPerMapUnit < yPixelsPerMapUnit)
	{
		mPixelsPerMapUnit = xPixelsPerMapUnit;
		double height = mapExtend->width()*clientSize->cy/clientSize->cx;
		m_curEnvelope.m_minY = centerPoint.m_y - height/2;
		m_curEnvelope.m_maxY = centerPoint.m_y + height/2;
	}
	else
	{
		mPixelsPerMapUnit = yPixelsPerMapUnit;
		double width = mapExtend->height()*clientSize->cx/clientSize->cy;
		m_curEnvelope.m_minX = centerPoint.m_x - width/2;
		m_curEnvelope.m_maxX = centerPoint.m_x + width/2;
	}    
}

void CMap2ClientTransform::transform2Client(double &x, double &y)
{
  //  if (m_sourceCRS && m_destCRS 
		//&& m_sourceCRS != m_destCRS
		//&& pj_is_latlong(m_sourceCRS))
  //  {
		//x*= DEG_TO_RAD;
		//y*= DEG_TO_RAD;
		//double z = 0;
		//pj_transform(m_sourProjection,m_destProjection,1, 0,&x,&y,&z);
  //  }
	//x = (x - mMapXMin)*mPixelsPerMapUnit*m_ratio + m_offset.m_x;
    //y = (mclientHeight - (y - mMapYMin)*mPixelsPerMapUnit)*m_ratio + m_offset.m_y;
	//double orgMapX,orgMapY;
	//orgMapX = (x + m_finalOffsetX)*m_finalRatio;
	//orgMapY = mclientHeight*m_zoomRatio - (y-m_finalOffsetY)*m_finalRatio;
	//double mapX,mapY;

	//{		
	//	transform2Map(orgMapX,orgMapY,mapX,mapY);
	//	mapX;
	//}
	//x = orgMapX;
	//y = orgMapY;
	/*x = (x + m_finalOffsetX)*m_finalRatio;
	y = m_clientSize.cy*m_zoomRatio - (y-m_finalOffsetY)*m_finalRatio;*/
	double clientX = x;
	double clientY = y;
	x = (x - m_curEnvelope.m_minX)*mPixelsPerMapUnit;
	y = m_clientSize.cy - (y - m_curEnvelope.m_minY)*mPixelsPerMapUnit;

	double mapX,mapY;
	transform2Map(x,y,mapX,mapY);
}

void CMap2ClientTransform::transform2Map(double &x, double &y,double& mapX,double& mapY)
{
	//if (m_sourceCRS && m_destCRS 
	//	&& m_sourceCRS != m_destCRS
	//	&& pj_is_latlong(m_sourceCRS))
	//{
	//	x*= DEG_TO_RAD;
	//	y*= DEG_TO_RAD;
	//	double z = 0;
	//	pj_transform(m_sourProjection,m_destProjection,1, 0,&x,&y,&z);
	//}
	//mapX = x/m_finalRatio - m_finalOffsetX;
	//mapY = (m_clientSize.cy*m_zoomRatio - y)/m_finalRatio + m_finalOffsetY;
	mapX = x/mPixelsPerMapUnit + m_curEnvelope.m_minX;
	mapY = m_clientSize.cy/mPixelsPerMapUnit + m_curEnvelope.m_minY- y/mPixelsPerMapUnit;
}

void CMap2ClientTransform::setSourceCRS(OGRSpatialReferenceH sourceCRS)
{
	m_sourceCRS = sourceCRS;
	OSRExportToProj4(m_sourceCRS,&m_sourProj4);
	m_sourProjection = pj_init_plus(m_sourProj4);
}

void CMap2ClientTransform::setDestCRS(OGRSpatialReferenceH destCRS)
{
	m_destCRS = destCRS;
	OSRExportToProj4(m_destCRS,&m_destProj4);
	m_destProjection = pj_init_plus(m_destProj4);
	if (!m_sourceCRS)
	{
		setSourceCRS(m_destCRS);
	}
}

void CMap2ClientTransform::offset(CMousePoint offset)
{
	m_curEnvelope.offset(-offset.m_x/mPixelsPerMapUnit,offset.m_y/mPixelsPerMapUnit);
}

void CMap2ClientTransform::zoomAtPoint(CMousePoint point, double ratio)
{
	if (m_preClientPoint.m_x - point.m_x < 0.000001 && m_preClientPoint.m_x - point.m_x > -0.000001
		&& m_preClientPoint.m_y - point.m_y < 0.000001 && m_preClientPoint.m_y - point.m_y > -0.000001)
	{
		
	}
	else
	{
		double clientX = point.m_x;
		double clientY = point.m_y;
		double mapX;
		double mapY;
		transform2Map(clientX,clientY,mapX,mapY);	
		m_preMapPoint.m_x = mapX;
		m_preMapPoint.m_y = mapY;
	}
	m_curEnvelope.scaleAtPoint(ratio,m_preMapPoint.m_x,m_preMapPoint.m_y);
	mPixelsPerMapUnit /= ratio;
	double clientX = m_preMapPoint.m_x;
	double clientY = m_preMapPoint.m_y;
	transform2Client(clientX,clientY);
	offset(CMousePoint(-clientX+point.m_x,-clientY + point.m_y));
	double clientX1 = m_preMapPoint.m_x;
	double clientY1 = m_preMapPoint.m_y;
	transform2Client(clientX1,clientY1);
	//setParameters(&m_clientSize,&m_curEnvelope);
	//m_curEnvelope.scaleAtPoint(ratio,m_preMapPoint.m_x,m_preMapPoint.m_y);
	//mPixelsPerMapUnit /= ratio;

	//double clientX = m_preMapPoint.m_x;
	//double clientY = m_preMapPoint.m_y;	
	//transform2Client(clientX,clientY);
}